/*Default Multithread Program in Eclipse SWT
 * Written by Seung Il Moon (simoon@networking.khu.ac.kr)
 * 2011.01.04
 *  */
package net.m2m.policyeditor.main;
import java.io.*;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.net.SocketException;
import java.util.StringTokenizer;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

public class MultiThreadedServer implements Runnable{

    protected int          serverPort   = 51718;
    protected ServerSocket serverSocket = null;
    protected boolean      isStopped    = false;
    protected Thread       runningThread= null;
    protected Shell m_shell;
    protected String tMessage;

    public MultiThreadedServer(int port, Shell p_shell){
        this.serverPort = port;
        m_shell = p_shell;
    }

    public void run(){
        synchronized(this){
            this.runningThread = Thread.currentThread();
        }
        
        openServerSocket();
        while(! isStopped()){
            Socket clientSocket = null;
            try {
                System.out.println("listening for connections");
                clientSocket = this.serverSocket.accept();
            } catch (IOException e) {
                if(isStopped()) {
                    System.out.println("Server Stopped.") ;
                    return;
                }
                throw new RuntimeException(
                    "Error accepting client connection", e);
            }
///
            System.out.println("Monitor connected to PE: ");
            DataInputStream is;
            PrintStream os;
            byte[]  bMessage = new byte[250];
            try 
            {
                is = new DataInputStream(clientSocket.getInputStream());
                os = new PrintStream(clientSocket.getOutputStream());
                int count = is.read(bMessage);
                //bMessage[count-1]= '\0';
                String tString = new String (bMessage);
                tMessage = tString.substring(0, count);
                if (count == -1)
                {
                    System.out.println("\r\nClient Disconnected ");
                    is.close();
                    os.close();
                    break;
                }
                if ((tString.indexOf("bye") == 1) || (tString.indexOf("bye") == 0))
                {
                    os.println("<bye>");
                    is.close();
                    os.close();
                    break;
                }
                System.out.println("\r\nMessage Received: " + tMessage );
                os.println("ack");
                clientSocket.close();
                Display.getDefault().syncExec(new Runnable() {
                    public void run() {
                    	///// Message Parser goes here.... parse String tMessage
                //System.out.println("Here I am before parse");
                parseMessage();
                //System.out.println("Here I am after parse");
                    }}); 
            } catch (IOException e) {
                //report exception somewhere.
                e.printStackTrace();

                
            }
            
         }
        System.out.println("Server Stopped.") ;
    }

///=\===\\=\=\
    
    private void parseMessage()
    {
        //tMessage = "<event><sn><node_id><SN-01><event_name><Humidity\\ValueHigh><event_message><The sensed value is greater than the Threshold value.><parameter><Humidity><value><57>";
    	StringTokenizer st = new StringTokenizer(tMessage, "<>");
        int tokenCount = st.countTokens();
        String [] tokens = new String[tokenCount];
//        String tString = "Details\r\n";
        for (int i=0; i < tokenCount ; i++)
        {
            tokens[i] = st.nextToken();
            
        }

        //<todo>//
        /// Show message to the User on Policy Editor GUI
        
        /// Node ID is 
        String NodeType = "";
        if (tokens[1].compareToIgnoreCase("sn") == 0)    
            NodeType = "Sensor Node";
        else if (tokens[1].compareToIgnoreCase("sngw") == 0)    
            NodeType = "Sensor Gateway";
        else if (tokens[1].compareToIgnoreCase("sp") == 0)    
            NodeType = "Smart Phone";
        String tShowMessage = "Node ID = " + tokens[3] + "\n\rNode Type = " 
        + NodeType + "\r\nEvent Name = " + tokens[5] + "\r\nMessage = " + tokens[7]
                + "\r\nDetails: " ;
        
        for (int i=8; i < tokenCount ; i+=4)
        {
            tShowMessage += "\r\nAttribute Name = " + tokens[i+1] + "\tAttribute Value = " + tokens[i+3];
        }
        System.out.println(tShowMessage);
        //System.out.println("Here Iam before show Message");
        showMessage(tShowMessage);
    }
    private void showMessage(String p_message)
    {
    	//Display display = new Display();
        //Shell shell = new Shell(display);
        MessageBox mb = new MessageBox (m_shell);
        mb.setText("PBNM Unhandled Event Monitored");
        mb.setMessage(p_message);
        int val = mb.open();
        
    }
    
    
    
//=\=\=\\=\=    
    

    private synchronized boolean isStopped() {
        return this.isStopped;
    }

    public synchronized void stop(){
        this.isStopped = true;
        try {
            this.serverSocket.close();
        } catch (IOException e) {
            throw new RuntimeException("Error closing server", e);
        }
    }

    private void openServerSocket() {
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
        } catch (IOException e) {
            throw new RuntimeException("Cannot open port 51717", e);
        }
    }

}


